using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using SBPweb.Localization;
using SBPweb.Contracts;
using SBPweb.Contracts.Options;
using SBPweb.Modules.Modularity;

namespace SBPweb.Modules.ModuleExplorer
{
	public partial class ModuleExplorerOptionsControl : UserControl
	{
		
		#region Private members

		private IOptionsService mOptionsService;
		private ModuleLoader mModuleLoader;
		private bool mIsInLoading;

		#endregion

		#region Constructor logic

		public ModuleExplorerOptionsControl(IOptionsService optionService, ModuleLoader moduleLoader)
		{
			InitializeComponent();

			mOptionsService = optionService;

			this.localizationExtender.SetResourceKey(this, "Title");
			this.localizationExtender.SetResourceKey(this, "ProgressControlCaptionWorkInProgress");
			this.localizationExtender.SetResourceKey(this, "ProgressControlLoadingModulText");
			this.localizationExtender.SetResourceKey(this, "ProgressControlUnLoadingModulText");

			LocalizationExtender.OnInvalidatedControls += new EventHandler(LocalizationExtender_OnInvalidatedControls);

			mOptionsService.OnApply -= new EventHandler(OptionsService_OnApply);
			mOptionsService.OnApply += new EventHandler(OptionsService_OnApply);

			mModuleLoader = moduleLoader;
			mModuleLoader.ModuleGroupLoaded += new EventHandler(ModuleLoader_ModuleGroupLoaded);
			mModuleLoader.ModuleLoaded += new EventHandler<ModuleEventArgs>(mModuleLoader_ModuleLoaded);

			ILayoutService layoutService = mModuleLoader.Services.Get<ILayoutService>();
			if (layoutService != null)
			{
				layoutService.LayoutLoaded += new EventHandler(layoutService_LayoutLoaded);
			}
		}

		#endregion

		#region Private methods

		private void FillCheckListBox()
		{
			clbModules.Items.Clear();
			foreach (ModuleGroup mg in mModuleLoader.ModuleGroups)
			{
				if (mg.ModuleGroupName == (string)cbModuleGroups.SelectedItem)
				{
					foreach (ModuleInfo mi in mg.Items)
					{
						clbModules.Items.Add(mi);
						clbModules.SetItemChecked(clbModules.Items.IndexOf(mi), mi.ModuleDescriptor.Loaded);
					}
					break;
				}
			}
			clbModules.Enabled = (string)cbModuleGroups.SelectedItem == mModuleLoader.CurrentModuleGroupName;
		}

		#endregion

		#region Event handlers

		private void ModuleLoader_ModuleGroupLoaded(object sender, EventArgs e)
		{
			mIsInLoading = true;
			cbModuleGroups.Items.Clear();
			foreach (ModuleGroup mg in mModuleLoader.ModuleGroups)
			{
				cbModuleGroups.Items.Add(mg.ModuleGroupName);
			}
			if (mModuleLoader.CurrentModuleGroupName != null)
			{
				cbModuleGroups.SelectedIndex = cbModuleGroups.Items.IndexOf(mModuleLoader.CurrentModuleGroupName);
			}
			FillCheckListBox();
			mIsInLoading = false;
		}

		private void mModuleLoader_ModuleLoaded(object sender, ModuleEventArgs e)
		{
			ModuleLoader_ModuleGroupLoaded(sender, e);
		}

		void layoutService_LayoutLoaded(object sender, EventArgs e)
		{
			ModuleLoader_ModuleGroupLoaded(sender, e);
		}

		private void OptionsService_OnApply(object sender, EventArgs e)
		{
			if (cbModuleGroups.SelectedItem == null)
			{
				return;
			}
			if (mModuleLoader.CurrentModuleGroupName != cbModuleGroups.SelectedItem.ToString())
			{
				ModuleBase optionsModule = mOptionsService as ModuleBase;
				SBPweb.Presentation.Windows.Forms.Controls.ProgressControl pc = null;
				if (optionsModule != null)
				{
					pc = new SBPweb.Presentation.Windows.Forms.Controls.ProgressControl(optionsModule);
				}
				try
				{
					if (pc != null)
					{
						pc.ProgressCaption = LocalizationExtender.GetString(this, "ProgressControlCaptionWorkInProgress");
					}
					optionsModule.Host.Smartparts.Add(pc);
					if (pc != null)
					{
						pc.ProgressText = string.Format("Loading module group: {0}", (string)cbModuleGroups.SelectedItem);
					}
					mModuleLoader.LoadModuleGroup((string)cbModuleGroups.SelectedItem);
					cbModuleGroups_SelectedIndexChanged(cbModuleGroups, new EventArgs());
				}
				finally
				{
					if (optionsModule != null && pc != null)
					{
						optionsModule.Host.Smartparts.Remove(pc);
						pc.Dispose();
					}
				}
			}
			else
			{
				ModuleBase optionsModule = mOptionsService as ModuleBase;
				Presentation.Windows.Forms.Controls.ProgressControl pc = null;
				if (optionsModule != null)
				{
					pc = new SBPweb.Presentation.Windows.Forms.Controls.ProgressControl(optionsModule);
					pc.ProgressCaption = LocalizationExtender.GetString(this, "ProgressControlCaptionWorkInProgress");
					optionsModule.Host.Smartparts.Add(pc);
				}

				bool moduleListChanged = false;
				cbModuleGroups.SelectedIndex = cbModuleGroups.Items.IndexOf(mModuleLoader.CurrentModuleGroupName);
				foreach (ModuleInfo mi in mModuleLoader.CurrentModuleList)
				{
					if (!mi.IsCoreModule)
					{
						try
						{
							if (!mi.ModuleDescriptor.Loaded && clbModules.IsModuleInfoChecked(mi))
							{
								pc.ProgressText = string.Format("{0}\n{1}", LocalizationExtender.GetString(this, "ProgressControlLoadingModulText"), mi.ModuleDescriptor.AssemblyName);
								mModuleLoader.LoadModule(mi);
								moduleListChanged = true;
							}
							if (mi.ModuleDescriptor.Loaded && !clbModules.IsModuleInfoChecked(mi) && mi.AllowUnload)
							{
								pc.ProgressText = string.Format("{0}\n{1}", LocalizationExtender.GetString(this, "ProgressControlUnLoadingModulText"), mi.ModuleDescriptor.AssemblyName);
								mModuleLoader.UnloadModule(mi);
								moduleListChanged = true;
							}
						}
						catch (Exception ex)
						{
							optionsModule.Host.LogManager.WriteError(this, ex.ToString(), "ModuleExplorer");
						}
					}
				}

				if (moduleListChanged)
				{
					pc.ProgressText = LocalizationExtender.GetString(this, "ProgressControlGeneratingContainerList");
					LocalizationExtender.GenerateContainerList();
				}

				if (optionsModule != null)
				{
					optionsModule.Host.Smartparts.Remove(pc);
					pc.Dispose();
				}
				Refresh();
			}
		}

		private void clbModules_ItemCheck(object sender, ItemCheckEventArgs e)
		{
			if (!mIsInLoading)
			{
				mOptionsService.IsModified = true;
			}
		}

		private void cbModuleGroups_SelectedIndexChanged(object sender, EventArgs e)
		{
			mOptionsService.IsModified = true;
			FillCheckListBox();
		}

		private void LocalizationExtender_OnInvalidatedControls(object sender, EventArgs e)
		{
			mOptionsService.RenameOptionsTab("Module explorer", LocalizationExtender.GetString(this, "Title"));
			ModuleExplorerOptionsControl_Resize(null, new EventArgs());
		}

		private void ModuleExplorerOptionsControl_Resize(object sender, EventArgs e)
		{
			cbModuleGroups.Width = this.Width - (cbModuleGroups.Left + 5);
		}

		#endregion

	}	

}
